#pragma once

#include <algorithm/analytical_model/algorithm/cuda/inter_op/Data.h>

#include <memory>

namespace solar::cuda
{
    class Receiver;
}

namespace solar::cuda::inter_op
{
    class Receiver
    {
        public:
            // Receiver(cudaStream_t stream = nullptr);
            virtual void init(float pixel_per_meter_for_receiver) const = 0;
            virtual void setResolution(float pixel_per_meter_for_receiver) const = 0;
            [[nodiscard]] virtual auto
            getFocusCenter(const Float3& heliostat_position) const -> Float3 = 0;
            void setResolution(const Int2& input) const;
            void setSize(const Float3& input) const;
            void setPosition(const Float3& input) const;
            void setNormal(const Float3& input) const;
            [[nodiscard]] auto getResolution() const -> Int2;
            [[nodiscard]] auto getSize() const -> Float3;
            [[nodiscard]] auto getPosition() const -> Float3;
            [[nodiscard]] auto getNormal() const -> Float3;
            [[nodiscard]] auto getSurfaceIndex() const -> int;
            void setSurfaceIndex(int index) const;
            /// @brief Allocate the final image matrix.
            void allocImage() const;
            /// @brief Clean the final image matrix.
            void cleanImageContent() const;
            void clear() const;

        protected:
            Receiver() = default;
            std::shared_ptr<solar::cuda::Receiver> delegate_ptr_;
    };
} // namespace solar::cuda::inter_op
